﻿/*
 * ====================================================================
 * Copyright (c) 2000-2006 MineHe.  All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.  The terms
 * are also available at http://www.minehe.net/projects/miucos/terms.aspx.
 * If newer versions of this license are posted there, you may use a
 * newer version instead, at your option.
 *
 * This software consists of voluntary contributions made by many
 * individuals.  For exact contribution history, see the revision
 * history and logs, available at http://www.minehe.net/projects/miucos/ or 
 * http://code.google.com/p/miucos/.
 * 
 * WARNNING!!!!!!
 * YOU CAN NOT USE THIS CODE FILE OR ANY CODES IN MIUCOS FILES FOR COMMERCIAL
 * SYSTEM OR PURPOSE.
 * ====================================================================
 */

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Xml.Serialization;
using System.Diagnostics;

namespace minehe.miucos.common
{
	/// <summary>
	/// 序列化实用工具类
	/// </summary>
	public static class SerializationUtils
	{
		#region Binary Serialization Methods

		#region Serialize Methods

		/// <summary>
		/// 二进制序列化a_object对象到a_filePath指定的文件中
		/// </summary>
		/// <param name="a_object">要序列化的对象</param>
		/// <param name="a_filePath">要写入序列化的文件</param>
		/// <returns>结果</returns>
		public static StatusResult SerializeToFile(object a_object, string a_filePath)
		{
			Debug.Assert((a_object != null) && (a_filePath != null) && (a_filePath.Trim() != ""));

			if (File.Exists(a_filePath) == false) return new StatusResult(ResultCodes.RC_NOTEXISTS);

			FileStream l_fs = null;
			try
			{
				try
				{
					l_fs = new FileStream(a_filePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
					BinaryFormatter l_bf = new BinaryFormatter();
					l_bf.Serialize(l_fs, a_object);
				}
				catch (Exception ex)
				{
					return new StatusResult(ResultCodes.RC_EXCEPTION, ex);
				}
			}
			finally
			{
				if (l_fs != null) l_fs.Close();
			}

			return new SucceedStatusResult();
		}
		/// <summary>
		/// 二进制序列化a_object对象为字节数组
		/// </summary>
		/// <param name="a_object">要序列化的对象</param>
		/// <returns>结果</returns>
		public static Result<byte[]> SerializeToBytes(object a_object)
		{
			Debug.Assert((a_object != null));

			MemoryStream l_ms = new MemoryStream();
			try
			{
				try
				{
					BinaryFormatter l_bf = new BinaryFormatter();
					l_bf.Serialize(l_ms, a_object);
				}
				catch (Exception ex)
				{
					return new Result<byte[]>(ResultCodes.RC_EXCEPTION, null, ex);
				}

				return new SucceedResult<byte[]>(l_ms.GetBuffer());
			}
			finally
			{
				if (l_ms != null) l_ms.Close();
			}
		}
		/// <summary>
		/// 二进制序列化a_object对象到a_stream指定的流中，写入位置从流当前位置开始
		/// </summary>
		/// <param name="a_object">要序列化的对象</param>
		/// <param name="a_stream">要写入的流</param>
		/// <returns>结果</returns>
		public static StatusResult SerializeToStream(object a_object, Stream a_stream)
		{
			Debug.Assert((a_object != null) && (a_stream != null) && (a_stream.CanWrite == true));

			try
			{
				BinaryFormatter l_bf = new BinaryFormatter();
				l_bf.Serialize(a_stream, a_object);
			}
			catch (Exception ex)
			{
				return new StatusResult(ResultCodes.RC_EXCEPTION, ex);
			}

			return new SucceedStatusResult();
		}

		#endregion

		#region Deserialize Methods

		/// <summary>
		/// 从指定文件中反二进制序列化
		/// </summary>
		/// <param name="a_filePath">要反序列化的文件</param>
		/// <returns>结果</returns>
		public static Result<object> DeSerializeFromFile(string a_filePath)
		{
			Debug.Assert((a_filePath != null) && (a_filePath.Trim() != ""));

			if (File.Exists(a_filePath) == false) return new Result<object>(ResultCodes.RC_NOTEXISTS);

			FileStream l_fs = null;
			try
			{
				try
				{
					l_fs = new FileStream(a_filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
					BinaryFormatter l_bf = new BinaryFormatter();
					object l_object = l_bf.Deserialize(l_fs);

					return new SucceedResult<object>(l_object);
				}
				catch (Exception ex)
				{
					return new Result<object>(ResultCodes.RC_EXCEPTION, null, ex);
				}
			}
			finally
			{
				if (l_fs != null) l_fs.Close();
			}
		}
		/// <summary>
		/// 从指定字节数组中反二进制序列化
		/// </summary>
		/// <param name="a_bytes">要反序列化的字节数组</param>
		/// <returns>结果</returns>
		public static Result<object> DeSerializeFromBytes(byte[] a_bytes)
		{
			Debug.Assert((a_bytes != null) && (a_bytes.Length > 0));

			MemoryStream l_ms = new MemoryStream(a_bytes);
			try
			{
				try
				{
					BinaryFormatter l_bf = new BinaryFormatter();
					object l_object = l_bf.Deserialize(l_ms);

					return new SucceedResult<object>(l_object);
				}
				catch (Exception ex)
				{
					return new Result<object>(ResultCodes.RC_EXCEPTION, null, ex);
				}
			}
			finally
			{
				if (l_ms != null) l_ms.Close();
			}
		}
		/// <summary>
		/// 从指定流中反二进制序列化，从流当前位置开始
		/// </summary>
		/// <param name="a_stream">要反序列化的流</param>
		/// <returns>结果</returns>
		public static Result<object> DeSerializeFromStream(Stream a_stream)
		{
			Debug.Assert((a_stream != null) && (a_stream.CanRead == true));

			try
			{
				try
				{
					BinaryFormatter l_bf = new BinaryFormatter();
					object l_object = l_bf.Deserialize(a_stream);

					return new SucceedResult<object>(l_object);
				}
				catch (Exception ex)
				{
					return new Result<object>(ResultCodes.RC_EXCEPTION, null, ex);
				}
			}
			finally
			{
			}
		}

		#endregion

		#endregion

		#region XML Serialization Methods

		#region Serialize Methods

		/// <summary>
		/// XML序列化a_object对象到a_filePath指定的文件中
		/// </summary>
		/// <param name="a_object">要序列化的对象</param>
		/// <param name="a_filePath">要写入序列化的文件</param>
		/// <returns>结果</returns>
		public static StatusResult XmlSerializeToFile(object a_object, string a_filePath)
		{
			Debug.Assert((a_object != null) && (a_filePath != null) && (a_filePath.Trim() != ""));

			if (File.Exists(a_filePath) == false) return new StatusResult(ResultCodes.RC_NOTEXISTS);

			FileStream l_fs = null;
			try
			{
				try
				{
					l_fs = new FileStream(a_filePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
					XmlSerializer l_xs = new XmlSerializer(a_object.GetType());
					l_xs.Serialize(l_fs, a_object);
				}
				catch (Exception ex)
				{
					return new StatusResult(ResultCodes.RC_EXCEPTION, ex);
				}
			}
			finally
			{
				if (l_fs != null) l_fs.Close();
			}

			return new SucceedStatusResult();
		}
		/// <summary>
		/// XML序列化a_object对象为字节数组
		/// </summary>
		/// <param name="a_object">要序列化的对象</param>
		/// <returns>结果</returns>
		public static Result<byte[]> XmlSerializeToBytes(object a_object)
		{
			Debug.Assert((a_object != null));

			MemoryStream l_ms = new MemoryStream();
			try
			{
				try
				{
					XmlSerializer l_xs = new XmlSerializer(a_object.GetType());
					l_xs.Serialize(l_ms, a_object);
				}
				catch (Exception ex)
				{
					return new Result<byte[]>(ResultCodes.RC_EXCEPTION, null, ex);
				}

				return new SucceedResult<byte[]>(l_ms.GetBuffer());
			}
			finally
			{
				if (l_ms != null) l_ms.Close();
			}
		}
		/// <summary>
		/// XML序列化a_object对象到a_stream指定的流中，写入位置从流当前位置开始
		/// </summary>
		/// <param name="a_object">要序列化的对象</param>
		/// <param name="a_stream">要写入的流</param>
		/// <returns>结果</returns>
		public static StatusResult XmlSerializeToStream(object a_object, Stream a_stream)
		{
			Debug.Assert((a_object != null) && (a_stream != null) && (a_stream.CanWrite == true));

			try
			{
				XmlSerializer l_xs = new XmlSerializer(a_object.GetType());
				l_xs.Serialize(a_stream, a_object);
			}
			catch (Exception ex)
			{
				return new StatusResult(ResultCodes.RC_EXCEPTION, ex);
			}

			return new SucceedStatusResult();
		}

		#endregion

		#region Deserialize Methods

		/// <summary>
		/// 从指定文件中反XML序列化
		/// </summary>
		/// <param name="a_type">反序列化的类型</param>
		/// <param name="a_filePath">要反序列化的文件</param>
		/// <returns>结果</returns>
		public static Result<object> XmlDeSerializeFromFile(Type a_type, string a_filePath)
		{
			Debug.Assert((a_filePath != null) && (a_filePath.Trim() != ""));

			if (File.Exists(a_filePath) == false) return new Result<object>(ResultCodes.RC_NOTEXISTS);

			FileStream l_fs = null;
			try
			{
				try
				{
					l_fs = new FileStream(a_filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
					XmlSerializer l_xs = new XmlSerializer(a_type);
					object l_object = l_xs.Deserialize(l_fs);

					return new SucceedResult<object>(l_object);
				}
				catch (Exception ex)
				{
					return new Result<object>(ResultCodes.RC_EXCEPTION, null, ex);
				}
			}
			finally
			{
				if (l_fs != null) l_fs.Close();
			}
		}
		/// <summary>
		/// 从指定字节数组中反XML序列化
		/// </summary>
		/// <param name="a_type">反序列化的类型</param>
		/// <param name="a_bytes">要反序列化的字节数组</param>
		/// <returns>结果</returns>
		public static Result<object> XmlDeSerializeFromBytes(Type a_type, byte[] a_bytes)
		{
			Debug.Assert((a_bytes != null) && (a_bytes.Length > 0));

			MemoryStream l_ms = new MemoryStream(a_bytes);
			try
			{
				try
				{
					XmlSerializer l_xs = new XmlSerializer(a_type);
					object l_object = l_xs.Deserialize(l_ms);

					return new SucceedResult<object>(l_object);
				}
				catch (Exception ex)
				{
					return new Result<object>(ResultCodes.RC_EXCEPTION, null, ex);
				}
			}
			finally
			{
				if (l_ms != null) l_ms.Close();
			}
		}
		/// <summary>
		/// 从指定流中反XML序列化，从流当前位置开始
		/// </summary>
		/// <param name="a_type">反序列化的类型</param>
		/// <param name="a_stream">要反序列化的流</param>
		/// <returns>结果</returns>
		public static Result<object> XmlDeSerializeFromStream(Type a_type, Stream a_stream)
		{
			Debug.Assert((a_stream != null) && (a_stream.CanRead == true));

			try
			{
				try
				{
					XmlSerializer l_xs = new XmlSerializer(a_type);
					object l_object = l_xs.Deserialize(a_stream);

					return new SucceedResult<object>(l_object);
				}
				catch (Exception ex)
				{
					return new Result<object>(ResultCodes.RC_EXCEPTION, null, ex);
				}
			}
			finally
			{
			}
		}
		/// <summary>
		/// 从指定UTF-8编码格式的XML文本字符串中反XML序列化
		/// </summary>
		/// <param name="a_type">反序列化的类型</param>
		/// <param name="a_stream">要反序列化的XML文本，文本编码要求utf-8</param>
		/// <returns>结果</returns>
		public static Result<object> XmlDeSerializeFromText(Type a_type, string a_string)
		{
			Debug.Assert((a_string != null) && (a_string != ""));

			return SerializationUtils.XmlDeSerializeFromBytes(a_type, Encoding.UTF8.GetBytes(a_string));
		}

		#endregion

		#endregion
	}
}
